#include "QDivaWindow.h"
#include "Socket.h"
#include "Command_Agent.h"
#include <process.h>       /// for using thread
#include <QtGui/QApplication>
#include "windows.h"
#include "lock.h"
#include "DIVA_Manager.h"
#include "ExplorBotLibrary.h"
#include "layout/LayoutLibrary.h"
#include <QMessageBox>
#include "CommandServer.h"

//////////////////////////////////////////////////////////////////////////
// xTitan test automation
#include <xTitanClient/xTitan.hpp>
#include "xSocketServer.h"
//////////////////////////////////////////////////////////////////////////

DIVA_Application* DIVA_Application::instance = NULL;	// singleton DIVA_Application

unsigned __stdcall createSever(void*) {
	//////////////////////////////////////////////////////////////////////////
	/// 建立server thread port 2000, 容許同時5連線
	SocketServer *in;
	if (xIsTesting()){ // If it is in testing mode, create testing purposed socket
		in = new xSocketServer(2000,5);
	} else{ // otherwise use the original socket.
		in = new SocketServer(2000,5);
	}
	//////////////////////////////////////////////////////////////////////////

	/// 接收連線
	Socket* s=in->Accept();
	std::string clientIP = s->PeerName();
	Command_Agent::initialize( clientIP );

	while (1) {


		// 加入傳送/接收者的label
		// 接收來自MinervaClient的訊息指令
		std::string r = s->ReceiveLine("[DIVAMainClient]$");
		assert(r.length() > 0);

		/// 先以換行為分隔 再以空格為分隔
		std::vector<std::string> returnMsg = Command_Agent::getInstance()->stringSplit(r,NEWLINE);
		returnMsg = Command_Agent::getInstance()->stringSplit(*(returnMsg.begin()),BLANK);

		/// 取得指令
		std::vector<std::string>::iterator itr = returnMsg.begin();

		if ((*itr).find(CMD_VISUALIZE)  != (*itr).npos) /// visualize
		{
			DIVA_Manager::getInstance()->lock(); 
			Command_Agent::getInstance()->visualize(*(itr+1));    
			DIVA_Manager::getInstance()->release();
		}
		else if (((*itr).find(CMD_UNFOLD3D)  != (*itr).npos) || ((*itr).find(CMD_UNFOLD2D)  != (*itr).npos) || ((*itr).find(CMD_UNFOLD1D)  != (*itr).npos) )/// unfold array
		{
			DIVA_Manager::getInstance()->lock(); 
			Command_Agent::getInstance()->unfoldArray(r);
			DIVA_Manager::getInstance()->release(); 
		}
		else if ((*itr).find(CMD_UNFOLD) != (*itr).npos) /// unfoldRef
		{
			DIVA_Manager::getInstance()->lock(); 
			Command_Agent::getInstance()->unfoldRef(*(itr+1));  
			DIVA_Manager::getInstance()->release();
		}
		else if ((*itr).find(CMD_FOLD)  != (*itr).npos) Command_Agent::getInstance()->fold(*(++itr));   /// fold 
		else if ((*itr).find(CMD_UPDATE)  != (*itr).npos) {
			DIVA_Manager::getInstance()->lock(); 
			Command_Agent::getInstance()->update(); /// update 
			DIVA_Manager::getInstance()->release();
		}
		else if ((*itr).find(PRINT) != (*itr).npos)
		{
			Command_Agent::getInstance()->printMessage(r); /// print
		}
	}
	return 0;
}

int main(int argc, char *argv[]){
	QApplication a(argc, argv);

	//////////////////////////////////////////////////////////////////////////
	// Try test automation if found "-t" in the arguments.
	QStringList args( a.arguments() );
	if ( args.size() > 1 ){
		int index = args.indexOf("-t");
		if ( index > 0 ){ // found "-t"
			xTryTestAutomation();
		}
	}
	//////////////////////////////////////////////////////////////////////////

	/* Create a thread to be the server */
	/*
	unsigned ret;
	_beginthreadex(0,0,createSever,0,0,&ret);
	*/
	CommandServer::initialize();
	CommandServer::instance().listen( QHostAddress::Any, 2000 );

	try{		
		QDivaWindow divaApp;
		Command_Agent::initialize( "" );
		divaApp.show();
		return a.exec();
	} catch (Ogre::Exception &e){
		QMessageBox msgBox;
		QString info;
		info += "An exception has occurred:<br>";
		info += e.getFullDescription().c_str();
		info += "<br>";
		info += "The program will exit.";
		msgBox.setText( info );
		msgBox.exec();
		return 1;
	} 
}
